package main

import (
	"bufio"
	"encoding/json"
	"fmt"
	"log"
	"net"
	"reflect"
	"sync"
)

type Server struct {
	services map[string]reflect.Value
	mu       sync.Mutex
}

func NewService() *Server {
	return &Server{
		services: make(map[string]reflect.Value),
	}
}

// 注册服务的方法
func (s *Server) Register(service any) error {
	s.mu.Lock()
	defer s.mu.Unlock()

	// 使用反射获取服务的类型
	serviceType := reflect.TypeOf(service)
	serviceName := serviceType.Elem().Name()

	if _, ok := s.services[serviceName]; ok {
		return fmt.Errorf("service %s already registered", serviceName)
	}

	s.services[serviceName] = reflect.ValueOf(service)

	return nil
}

type Request struct {
	Method string `json:"method"`
	Args   []int  `json:"args"`
}

func (s *Server) HandleRequest(conn net.Conn) {
	var methodName string

	reader := bufio.NewReader(conn)

	// 读取一行数据，可能包含 JSON 数据
	data, err := reader.ReadString('\n')
	if err != nil {
		log.Fatal("Error reading data:", err)
	}

	var request Request
	err = json.Unmarshal([]byte(data), &request)
	if err != nil {
		log.Fatal("Error unmarshalling JSON:", err)
	}

	// 查找已注册的服务
	s.mu.Lock()
	service, exists := s.services["Arith"] // 注意，检查服务名称，必须一致
	s.mu.Unlock()

	if !exists {
		fmt.Fprintln(conn, "Error: service not found")
		return
	}

	methodName = request.Method

	fmt.Println("methodName", methodName)
	// 获取 Arith 服务的 Add 方法
	method := service.MethodByName(methodName)
	fmt.Println("method:", method)
	if !method.IsValid() {
		fmt.Fprintln(conn, "Error: method not found")
		return
	}

	// 获取请求参数，确保 args 是切片或数组类型
	fmt.Println(request.Args)
	args := request.Args
	fmt.Println(args)
	// if !ok {
	// 	fmt.Fprintln(conn, "Error: invalid arguments format")
	// 	return
	// }

	// 处理方法的参数
	reflectArgs := make([]reflect.Value, len(args))
	for i, arg := range args {
		reflectArgs[i] = reflect.ValueOf(arg) // 转换为 reflect.Value 类型
	}

	fmt.Println(reflectArgs)
	result := method.Call(reflectArgs) // 使用 reflectArgs 调用方法

	if len(result) > 0 {
		fmt.Println("Result:", result[0].Int()) // 注意：结果需要从reflect.Value转换回原始类型
	}

	// 发送响应
	fmt.Fprintln(conn, result)
}

// 示例服务：加法
type Arith struct{}

// 加法方法
func (a *Arith) Add(num1, num2 int) int {

	// 假设传入的 args 是两个整型数值
	result := num1 + num2

	return result
}

func main() {
	server := NewService()

	arith := &Arith{}

	if err := server.Register(arith); err != nil {
		log.Fatal("Error registering service:", err)
	}

	ln, err := net.Listen("tcp", ":1234")
	if err != nil {
		log.Fatal("Error starting server:", err)
	}
	defer ln.Close()

	fmt.Println("Server is running on port 1234...")

	for {
		conn, err := ln.Accept()
		if err != nil {
			log.Fatal("Error accepting connection:", err)
		}

		go server.HandleRequest(conn)
	}
}
